home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / SmallTalk / SequenceableCollection.st < prev    next >
Text File  |  1995-08-25  |  10KB  |  353 lines

  1. "======================================================================
  2. |
  3. |   SequenceableCollection Method Definitions
  4. |
  5.  ======================================================================"
  6.  
  7.  
  8. "======================================================================
  9. |
  10. | Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  11. | Written by Steve Byrne.
  12. |
  13. | This file is part of GNU Smalltalk.
  14. |
  15. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  16. | under the terms of the GNU General Public License as published by the Free
  17. | Software Foundation; either version 1, or (at your option) any later version.
  18. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  19. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  21. | details.
  22. | You should have received a copy of the GNU General Public License along with
  23. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  24. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  25. |
  26.  ======================================================================"
  27.  
  28.  
  29. "
  30. |     Change Log
  31. | ============================================================================
  32. | Author       Date       Change 
  33. | sbb         16 Mar 91      Class creation now separate statement.
  34. |
  35. | sbb         29 Dec 90      Added hash function.
  36. |
  37. | sbb         29 Dec 90      Added = test to check sub elements for equality.
  38. |
  39. | sbb         20 Sep 90      Fixed indexOfSubCollection (it was off by one and did
  40. |              too much computation.
  41. |
  42. | sbyrne     19 Sep 89      Converted to use real method categories.
  43. |
  44. | sbyrne     25 Apr 89      created.
  45. |
  46. "
  47.  
  48. Collection variableSubclass: #SequenceableCollection
  49.        instanceVariableNames: ''
  50.        classVariableNames: ''
  51.        poolDictionaries: ''
  52.        category: nil
  53. !
  54.  
  55. SequenceableCollection comment: 
  56. 'My instances represent collections of objects that are ordered.  I provide
  57. some access and manipulation methods.' !
  58.  
  59.  
  60. !SequenceableCollection methodsFor: 'basic'!
  61.  
  62. atAll: aCollection put: anObject
  63.     aCollection do: [ :index | self at: index put: anObject ]
  64. !
  65.  
  66. atAllPut: anObject
  67.     1 to: self size do: [ :index | self at: index put: anObject ]
  68. !
  69.  
  70. first
  71.     ^self at: 1
  72. !
  73.  
  74. last
  75.     self size < 1 ifTrue: [ ^self error: 'last not defined with no elements' ].
  76.     ^self at: self size
  77. !
  78.  
  79. indexOf: anElement ifAbsent: exceptionBlock
  80.     1 to: self size do: [ :index | (self at: index) = anElement
  81.                                      ifTrue: [ ^index ] ].
  82.     ^exceptionBlock value
  83. !
  84.  
  85. indexOf: anElement
  86.     ^self indexOf: anElement ifAbsent: [ ^0 ]
  87. !
  88.  
  89. = aCollection
  90.     | size |
  91.     self == aCollection ifTrue: [ ^true ].
  92.     self species == aCollection species ifFalse: [ ^false ].
  93.     (size _ self size) == aCollection size ifFalse: [ ^false ].
  94.     1 to: size do:
  95.     [ :i | (self at: i) = (aCollection at: i)
  96.            ifFalse: [ ^false ] ].
  97.     ^true
  98. !
  99.  
  100. hash
  101.     "Return the hash value of the array"
  102.     "### I don't like this hashing algorithm"
  103.     | hashValue |
  104.     hashValue _ 0.
  105.     self do: [ :element | hashValue _ ((hashValue bitShift: 1)
  106.                                         bitXor:  element hash)
  107.                     bitAnd: 16r1FFFFFFF ].
  108.     ^hashValue
  109. !!
  110.  
  111.  
  112.  
  113. !SequenceableCollection methodsFor: 'nonpublic methods'!
  114.  
  115. matchSubCollection: aSubCollection startingAt: anIndex
  116.     2 to: aSubCollection size do:
  117.         [ :index | (self at: anIndex + index - 1) ~= (aSubCollection at: index)
  118.                    ifTrue: [ ^false ]
  119.     ].
  120.     ^true
  121. !
  122.  
  123. indexOfSubCollection: aSubCollection startingAt: anIndex
  124.     ifAbsent: exceptionBlock
  125.     | selfSize subSize |
  126.     subSize  _ aSubCollection size.
  127.     selfSize _ self size.
  128.     anIndex + subSize - 1 <= selfSize ifTrue:
  129.     [ anIndex to: selfSize - subSize + 1 do:
  130.           [:index | (self at: index) = (aSubCollection at: 1)
  131.                 ifTrue: [(self matchSubCollection: aSubCollection
  132.                        startingAt: index)
  133.                      ifTrue: [^index]
  134.                      ]
  135.                 ]
  136.           ].
  137.     ^exceptionBlock value
  138. !
  139.  
  140. "
  141. ""indexOfSubCollection: aSubCollection startingAt: anIndex
  142. ""                      ifAbsent: exceptionBlock
  143. ""    | selfSize subSize |
  144. ""    subSize _ aSubCollection size.
  145. ""    selfSize _ self size.
  146. ""    anIndex + subSize <= selfSize ifTrue:
  147. ""        [ 1 to: subSize do:
  148. ""            [ :index | (aSubCollection at: index) = (self at: anIndex + index - 1)
  149. ""                    ifTrue: [ (self matchSubCollection: aSubCollection
  150. ""                           startingAt: index)
  151. ""                       ifTrue: [ ^index ]
  152. ""                        ]
  153. ""        ] 
  154. ""        ].
  155. ""    ^exceptionBlock value
  156. ""!
  157. "
  158. indexOfSubCollection: aSubCollection startingAt: anIndex
  159.     ^self indexOfSubCollection: aSubCollection startingAt: anIndex
  160.         ifAbsent: [ ^0 ]
  161. !
  162.  
  163. replaceFrom: start to: stop with: replacementCollection startingAt: repStart
  164.     (self == replacementCollection and: [ repStart ~= 1 ])
  165.         ifTrue: [ ^self error: 'replaceFrom:to:with:startingAt: called for 
  166. in-place replacement, but starting index was not 1' ].
  167.     "speed this up by making it zero based, otherwise we have to subtract
  168.      1 from each use of index, and add one to the range"
  169.     0 to: stop - start  do:
  170.         [ :index |
  171.       self at: (start + index)
  172.                put: (replacementCollection at: (repStart + index)) ]
  173. !
  174.  
  175. replaceFrom: start to: stop with: replacementCollection
  176.     (stop - start + 1) ~= replacementCollection size
  177.         ifTrue: [ ^self error: 'replacement range does not equal size of
  178. replacement collection' ].
  179.     self replaceFrom: start to: stop with: replacementCollection startingAt: 1
  180. !!
  181.  
  182.  
  183.  
  184. !SequenceableCollection methodsFor: 'copying SequenceableCollections'!
  185.  
  186. , aSequenceableCollection
  187.     | newCollection |
  188.     newCollection _ self species new: (self size + aSequenceableCollection size).
  189.     newCollection replaceFrom: 1 to: self size with: self.
  190.     newCollection replaceFrom: (self size) + 1
  191.                   to: self size + aSequenceableCollection size
  192.           with: aSequenceableCollection.
  193.     ^newCollection
  194. !
  195.  
  196. copyFrom: start to: stop
  197.     | newCollection len |
  198.     len _ stop - start + 1.
  199.     newCollection _ self species new: len.
  200.     newCollection replaceFrom: 1 to: len with: self startingAt: start.
  201.     ^newCollection
  202. !
  203.  
  204. copyReplaceAll: oldSubCollection with: newSubCollection
  205.     | numOld newCollection sizeDifference newSubSize oldSubSize
  206.       newStart oldStart copySize index |
  207.     numOld _ self countSubCollectionOccurrencesOf: oldSubCollection.
  208.     newSubSize _ newSubCollection size.
  209.     sizeDifference _ newSubSize - oldSubCollection size + 1.
  210.     newCollection _ self species new: (self size - (sizeDifference * numOld)).
  211.     oldStart _ newStart _ 1.
  212.     [ index _ self indexOfSubCollection: oldSubCollection
  213.                    startingAt: oldStart.
  214.       index > 0 ] whileTrue:
  215.         [ copySize _ index - oldStart + 1.
  216.       newCollection replaceFrom: newStart
  217.                     to: newStart + copySize - 1
  218.             with: self
  219.             startingAt: oldStart.
  220.       newStart _ newStart + copySize - 1.
  221.       newCollection replaceFrom: newStart
  222.                     to: newStart + newSubSize - 1
  223.             with newSubCollection.
  224.           oldStart _ oldStart + copySize.
  225.           newStart _ newStart + newSubSize ].
  226.     "Copy the remaining part of self onto the tail of the new collection."
  227.     newCollection replaceFrom: newStart
  228.                  to: newCollection size
  229.          with: self
  230.          startingAt: oldStart.
  231.     ^newCollection
  232. !
  233.  
  234. copyReplaceFrom: start to: stop with: replacementCollection
  235.     | newCollection newSize repSize |
  236.     "### check for bounds "
  237.     repSize _ replacementCollection size.
  238.     newSize _ self size + repSize - (stop - start + 1).
  239.     newCollection _ self species new: newSize.
  240.     newCollection replaceFrom: 1 to: start - 1 with: self startingAt: 1.
  241.     newCollection replaceFrom: start
  242.                   to: start + repSize - 1
  243.           with: replacementCollection.
  244.     newCollection replaceFrom: start + repSize
  245.                   to: newCollection size
  246.           with: self
  247.           startingAt: stop + 1.
  248.     ^newCollection
  249. !
  250.  
  251. copyWith: newElement
  252.     | newCollection len |
  253.     len _ self size + 1.
  254.     newCollection _ self species new: len.
  255.     newCollection replaceFrom: 1 to: self size with: self.
  256.     newCollection at: len put: newElement.
  257.     ^newCollection
  258. !
  259.  
  260. copyWithout: oldElement
  261.     | newCollection numOccurrences i |
  262.     numOccurrences _ 0.
  263.     self do:
  264.         [ :element |
  265.       element = oldElement
  266.         ifTrue: [ numOccurrences _ numOccurrences + 1 ] ].
  267.     newCollection _ self species new: (self size - numOccurrences).
  268.     i _ 1.
  269.     self do:
  270.         [ :element |
  271.       element ~= oldElement
  272.         ifTrue: [ newCollection at: i put: element.
  273.                   i _ i + 1 ]
  274.     ].
  275.     ^newCollection
  276. !!
  277.  
  278.  
  279.  
  280. !SequenceableCollection methodsFor: 'enumerating'!
  281.  
  282. do: aBlock
  283.     "Evaluate aBlock for all elements in the sequenceable collection"
  284.     1 to: self size do:
  285.         [ :i | aBlock value: (self at: i) ]
  286. !
  287.  
  288. findFirst: aBlock
  289.     "Returns the index of the first element of the sequenceable collection
  290.     for which aBlock returns true"
  291.     1 to: self size do:
  292.         [ :i | (aBlock value: (self at: i))
  293.              ifTrue: [ ^i ] ].
  294.     ^0
  295. !
  296.  
  297. findLast: aBlock
  298.     self size to: 1 by: -1 do:
  299.         [ :i | (aBlock value: (self at: i))
  300.              ifTrue: [ ^i ] ].
  301.     ^0
  302. !
  303.  
  304. reverseDo: aBlock
  305.     self size to: 1 by: -1 do:
  306.         [ :i | aBlock value: (self at: i) ]
  307. !
  308.  
  309. with: aSequenceableCollection do: aBlock
  310.     self size = aSequenceableCollection size
  311.         ifFalse:
  312.         [ ^self error: 'sequenceable collections must have same size' ].
  313.     1 to: self size do:
  314.         [ :i | aBlock value: (self at: i)
  315.                   value: (aSequenceableCollection at: i) ]
  316. !!
  317.  
  318.  
  319.  
  320. !SequenceableCollection methodsFor: 'private methods'!
  321.  
  322. countSubCollectionOccurrencesOf: aSubCollection
  323.     | colIndex subColIndex count |
  324.     colIndex _ 1.
  325.     count _ 0.
  326.     [ subColIndex _ self indexOfSubCollection: aSubCollection
  327.                          startingAt: colIndex.
  328.       subColIndex > 0 ] whileTrue:
  329.           [ count _ count + 1.
  330.       colIndex _ colIndex + aSubCollection size ].
  331.     ^count
  332. !
  333.  
  334. grow
  335.     | newCollection |
  336. "    self class == ByteArray 
  337.     ifTrue: [  'growing ' print. self basicPrint.
  338.            self basicSize printNl.
  339.            Smalltalk backtrace   ]."
  340.   
  341.     newCollection _ self species new: self basicSize + self growSize.
  342.     newCollection replaceFrom: 1 to: self size with: self.
  343.     ^self become: newCollection
  344. !
  345.     
  346. growSize
  347.     ^10                "a randomly chosed number"
  348.  
  349. !!
  350.  
  351.